﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using DDDProject.Aspects;
using DDDProjectSample.Domain.Repositories;
using DDDProjectSample.Domain.Errors;

namespace DDDProjectSample.Domain
{
    public class Forum : Entity
    {
        private String _title;
        private String _description;

        [InjectComponent]
        private ITopicRepository _topicRepository;

        /// <summary>
        /// Creates a new instance of class Forum
        /// </summary>
        protected Forum()
        {
        }

        /// <summary>
        /// Creates a new instance of class Forum
        /// </summary>
        /// <param name="title">Title of the forum</param>
        /// <param name="description">Description of the forum</param>
        public Forum(
            String title,
            String description)
        {
            _title = title;
            _description = description;
        }


        /// <summary>
        /// Gets the forum's title
        /// </summary>
        public virtual String Title
        {
            get { return _title; }
        }

        /// <summary>
        /// Gets the forum's description
        /// </summary>
        public virtual String Description
        {
            get { return _description; }
        }

        /// <summary>
        /// Adds a new topic to the forum
        /// </summary>
        /// <param name="title">Title of the topic</param>
        /// <param name="author">Author of the topic</param>
        /// <param name="messageText">Text of the first message of the topic</param>
        /// <returns>The new created topic</returns>
        public virtual Topic AddTopic(
                String title,
                Member author,
                String messageText)
        {
            // --------------------------------------------------------------------
            // Note : Here we have an example of a business rule that is checked. 
            // The business rule is the following : a user cannot creates more than 
            // 3 topics in a day. The "CheckMaximumTopicsCreation" method checks 
            // this rule and throw a DomainError if the rule is not satisfied.
            // --------------------------------------------------------------------

            // First check if the author hasn't already created 3 topics last 24 hours
            CheckMaximumTopicsCreation(author);

            // Creates the topic
            Topic topic = new Topic(title, this, author);

            // Saves the topic
            _topicRepository.Save(topic);

            // Creates the first message of the topic
            topic.AddMessage(messageText, author);

            // Returns the topic
            return topic;
        }

        /// <summary>
        /// Checks if the author hasn't already created 3 topics last 24 hours
        /// </summary>
        /// <param name="author">User that wants to create the topic</param>
        /// <exception cref="DomainException">A DomainException is thrown if the user has already 
        /// created 3 topics last 24 hours</exception>
        private void CheckMaximumTopicsCreation(Member author)
        {
            DateTime date2 = DateTime.Now;
            DateTime date1 = date2.AddHours(-24);

            int nbTopicsCreatedByUser = _topicRepository.CountByUserId(author.Id, date1, date2);

            if (nbTopicsCreatedByUser >= 3)
            {
                throw new DomainError(
                    "You have already created 3 topics last 24 hours. Please retry later.");
            }
        }
    }
}
